/*
 * Unbuffered input will be used in the game itself and the buffered one will be use for states
 * which should be treated as menus.
 */

#ifndef __GameManager_H__
#define __GameManager_H__

#include <vector>
#include <Ogre.h>
#include <OIS/OIS.h>

#include "DeviceManager.h"
#include "GUIManager.h"

using namespace Ogre;

class GameState;

class GameManager : public Ogre::Singleton<GameManager>, public Ogre::FrameListener, public Ogre::WindowEventListener, public OIS::KeyListener, public OIS::MouseListener
{
	public:
		GameManager();
		~GameManager();

		void start(GameState* state);
		void changeState(GameState* state);
		void pushState(GameState* state);
		void popState();

		static GameManager& getSingleton(void);
		static GameManager* getSingletonPtr(void);

	protected:
		Root* mRoot;
		RenderWindow* mWindow;
		DeviceManager* mDeviceManager;
		GUIManager* mGUIManager;

		void setupResources(void);
		bool configure(void);
		void createResourceListener(void);
		void loadResources(void);
		
		bool keyPressed( const OIS::KeyEvent &arg );
		bool keyReleased( const OIS::KeyEvent &arg );

		bool mouseMoved( const OIS::MouseEvent &arg );
		bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
		bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id );

		bool frameStarted(const Ogre::FrameEvent& evt);
		bool frameEnded(const Ogre::FrameEvent& evt);

		void windowResized(RenderWindow* rw);
		void windowClosed(RenderWindow* rw);

	private:
		std::vector<GameState*> mStates;
};

#endif